package com.example.demo.controller.train;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.base.config.auth.UserInfoShareHolder;
import com.example.demo.base.login.dto.UserCache;
import com.example.demo.domain.entity.TrainClass;
import com.example.demo.domain.entity.TrainClassHomework;
import com.example.demo.domain.entity.TrainClassUser;
import com.example.demo.domain.entity.TrainCommitRecord;
import com.example.demo.domain.entity.TrainHomework;
import com.example.demo.domain.entity.TrainHomeworkProblem;
import com.example.demo.domain.model.HomeWorkForm;
import com.example.demo.domain.model.Question;
import com.example.demo.domain.vo.ClassUserSubmitInfoVo;
import com.example.demo.domain.vo.HomeWorkDetailVo;
import com.example.demo.dto.ResponseDto;
import com.example.demo.enums.HomeWorkStatus;
import com.example.demo.enums.TrainSubmitStatus;
import com.example.demo.enums.UserIdentifyEnum;
import com.example.demo.param.TrainClassUserParam;
import com.example.demo.param.TrainHomeworkParam;
import com.example.demo.service.TrainClassHomeworkService;
import com.example.demo.service.TrainClassService;
import com.example.demo.service.TrainClassUserService;
import com.example.demo.service.TrainCommitRecordService;
import com.example.demo.service.TrainHomeworkProblemService;
import com.example.demo.service.TrainHomeworkService;
import com.example.demo.utils.BeanCopyUtil;
import com.example.demo.utils.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 培训模块-作业
 * @author liguang03
 * @date 2024/2/1
 */
@Controller
@Slf4j
@RequestMapping("/train/train-homework")
public class TrainHomeWorkController {


    @Resource
    private TrainHomeworkService trainHomeworkService;

    @Resource
    private TrainHomeworkProblemService trainHomeworkProblemService;


    @Resource
    private TrainClassService trainClassService;


    @Resource
    private TrainClassHomeworkService trainClassHomeworkService;

    @Resource
    private TrainCommitRecordService trainCommitRecordService;


    @Resource
    private TrainClassUserService trainClassUserService;



    /**
     * 创建一个作业
     * @param form
     * @return
     */
    @RequestMapping("/create")
    @ResponseBody
    public ResponseDto<TrainHomework> createTrainClass(@RequestBody HomeWorkForm form) {
        UserCache userInfo = UserInfoShareHolder.getUserInfo();
        if (form == null || userInfo.getUser() == null) {
            return new ResponseDto().buildFail("参数为空");
        }
        List<Question> questionDetail = form.getQuestionDetail();
        if (CollectionUtils.isEmpty(questionDetail)){
            return new ResponseDto().buildFail("没有选择题目");
        }
        int sum = questionDetail.stream().mapToInt(Question::getScore).sum();
        if (!Objects.equals(sum,form.getTotalScore())){
            return new ResponseDto().buildFail("题目分数与总分不匹配");
        }
        TrainHomework trainHomework = new TrainHomework();
        trainHomework.setTitle(form.getTitle());
        trainHomework.setCreateTime(new Date());
        trainHomework.setCreator(userInfo.getUser().getId());
        trainHomework.setCompanyId(userInfo.getCompanyId());
        trainHomework.setStatus(HomeWorkStatus.ENABLE.getKey());
        trainHomework.setNotes(form.getNotes());
        trainHomework.setTotalScore(form.getTotalScore());
        trainHomework.setLanguage(form.getLanguage());
        trainHomework.setCommitTimes(form.getCommitTimes());
        trainHomework.setBeginTime(form.getBeginTime());
        trainHomework.setEndTime(form.getEndTime());
        boolean save = trainHomeworkService.save(trainHomework);
        if (!save){
            return new ResponseDto().buildFail("创建作业失败");
        }
        Long homeworkId = trainHomework.getId();
        log.info("【创建作业】操作人:{}, id:{}. 题目信息:{}", JSONUtil.toJsonStr(userInfo),
                homeworkId, JSONUtil.toJsonStr(form));
        List<TrainHomeworkProblem> trainHomeworkProblems = new ArrayList<>();
        questionDetail.forEach(question -> {
            TrainHomeworkProblem trainHomeworkProblem = new TrainHomeworkProblem();
            trainHomeworkProblem.setHomeworkId(homeworkId);
            trainHomeworkProblem.setProblemId(question.getProblemId());
            trainHomeworkProblem.setScore(question.getScore());
            trainHomeworkProblems.add(trainHomeworkProblem);
        });
        trainHomeworkProblemService.saveBatch(trainHomeworkProblems);
        return new ResponseDto().buildSucceedHasData(trainHomework);
    }


    /**
     *  启用/禁用作业
     * @param id 作业id
     * @param status 状态，1 启用， 2禁用
     * @return
     */
    @RequestMapping("/status-operate")
    @ResponseBody
    public ResponseDto operateTrainClass(Long id, Integer status) {
        UserCache userInfo = UserInfoShareHolder.getUserInfo();
        if (userInfo.getUser() == null) {
            return new ResponseDto().buildFail("未登录");
        }
        TrainHomework trainHomework = trainHomeworkService.getById(id);
        if (!Objects.equals(trainHomework.getCompanyId(), userInfo.getCompanyId())){
            return new ResponseDto().buildFail("无权限操作");
        }
        //校验是否有学生提交
        List<TrainHomeworkProblem> trainHomeworkProblems = trainHomeworkProblemService.queryByHwId(id);
        if (CollectionUtils.isEmpty(trainHomeworkProblems)){
            return new ResponseDto().buildFail("该作业无题目");
        }
        TrainHomeworkProblem trainHomeworkProblem = trainHomeworkProblems.get(0);
        List<TrainCommitRecord> trainCommitRecords = trainCommitRecordService.queryByHwIdAndPIdAndClassId(id, trainHomeworkProblem.getProblemId(), null);
        List<TrainCommitRecord> collect = trainCommitRecords.stream().filter(trainCommitRecord -> CommonUtil.isNotNullId(trainCommitRecord.getSubmitId())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(collect)){
            return new ResponseDto().buildFail("已有学生提交作业，不允许禁用");
        }
        trainHomework.setStatus(status);
        trainHomeworkService.updateById(trainHomework);
        return new ResponseDto().buildSucceed();
    }


    /**
     * 分页获取所有自己创建的作业
     * @param param
     * @return
     */
    @RequestMapping("/all-homework")
    @ResponseBody
    public ResponseDto<Page<TrainHomework>> getAllHomeWork(TrainHomeworkParam param){
        UserCache userInfo = UserInfoShareHolder.getUserInfo();
        if (userInfo.getUser() == null){
            return new ResponseDto<>().buildFail("未登录");
        }
        if (param.getCreatorId() == null) {
            param.setCreatorId(userInfo.getUser().getId());
        }
        if (param.getCompanyId() != null) {
            if (!Objects.equals(param.getCompanyId(), userInfo.getCompanyId())
                    && !UserIdentifyEnum.superAdmin.getIdentify().equals(userInfo.getUser().getIdentify())){
                return new ResponseDto<>().buildFail("无权限查询");
            }
        }

        Page<TrainHomework> trainHomeworkPage = trainHomeworkService.queryByParam(param);
        return new ResponseDto<Page<TrainHomework>>().buildSucceedHasData(trainHomeworkPage);

    }


    /**
     * 根据作业id 批量移除某个题目
     * @param homeworkId
     * @param problemId
     * @return
     */
    @RequestMapping("/remove/problem")
    @ResponseBody
    public ResponseDto removeProblem(Long homeworkId, List<Long> problemId){
        UserCache userInfo = UserInfoShareHolder.getUserInfo();
        TrainHomework homework = trainHomeworkService.getById(homeworkId);
        if (homework == null || Objects.equals(userInfo.getCompanyId(), homework.getCompanyId())){
            return new ResponseDto().buildFail("无权限操作");
        }
        trainHomeworkProblemService.removeByHwIdAndProblemId(homeworkId, problemId);
        return new ResponseDto().buildSucceed();
    }




    /**
     * 更新作业信息
     * @param form
     * @return
     */
    @RequestMapping("/update")
    @ResponseBody
    public ResponseDto updateTrainClassHomework(@RequestBody HomeWorkForm form) {
        UserCache userInfo = UserInfoShareHolder.getUserInfo();
        if (form == null || CommonUtil.isNullId(form.getHomeworkId()) || userInfo.getUser() == null) {
            return new ResponseDto().buildFail("参数为空");
        }
        TrainHomework trainHomework = new TrainHomework();
        trainHomework.setId(form.getHomeworkId());
        trainHomework.setTitle(StringUtils.isNotBlank(form.getTitle()) ? form.getTitle() : null);
        trainHomework.setStatus(HomeWorkStatus.ENABLE.getKey());
        trainHomework.setNotes(StringUtils.isNotBlank(form.getNotes()) ? form.getNotes() : null);
        trainHomework.setLanguage(StringUtils.isNotBlank(form.getLanguage()) ? form.getLanguage() : null);
        trainHomework.setCommitTimes(form.getCommitTimes() == null ? null : form.getCommitTimes());
        trainHomework.setBeginTime(form.getBeginTime() == null ? null : form.getBeginTime());
        trainHomework.setEndTime(form.getEndTime() == null ? null : form.getEndTime());
        long newTotalScore = 0L;
        if (form.getTotalScore() != null) {
            trainHomework.setTotalScore(form.getTotalScore());
            newTotalScore = form.getTotalScore();
        }else {
            TrainHomework byId = trainHomeworkService.getById(form.getHomeworkId());
            newTotalScore = byId.getTotalScore();
        }


        boolean save = trainHomeworkService.updateById(trainHomework);
        if (!save){
            return new ResponseDto().buildFail("更新作业失败");
        }
        Long homeworkId = trainHomework.getId();
        log.info("【更新作业】操作人:{}, id:{}. 题目信息:{}", JSONUtil.toJsonStr(userInfo),
                homeworkId, JSONUtil.toJsonStr(form));
        List<TrainHomeworkProblem> trainHomeworkProblems = new ArrayList<>();
        //处理题目
        List<Question> questionDetail = form.getQuestionDetail();
        if (CollectionUtils.isNotEmpty(questionDetail)){
            List<TrainHomeworkProblem> trainHomeworkProblemsFormDb = trainHomeworkProblemService.queryByHwId(form.getHomeworkId());
            List<Question> needDelete = new ArrayList<>();
            for (TrainHomeworkProblem trainHomeworkProblem : trainHomeworkProblemsFormDb) {
                Question question = new Question();
                question.setProblemId(trainHomeworkProblem.getProblemId());
                question.setScore(trainHomeworkProblem.getScore());
                if (questionDetail.contains(question)){
                    questionDetail.remove(question);
                }else {
                    needDelete.add(question);
                }
            }
            if (needDelete.size() != 0){
                long sum = questionDetail.stream().mapToLong(Question::getScore).sum();
                if (!Objects.equals(sum,newTotalScore)){
                    return new ResponseDto().buildFail("题目分数与总分不匹配");
                }
                List<Long> problemIds = needDelete.stream().map(Question::getProblemId).collect(Collectors.toList());
                trainHomeworkProblemService.deleteByProblemIds(problemIds);
                questionDetail.forEach(question -> {
                    TrainHomeworkProblem trainHomeworkProblem = new TrainHomeworkProblem();
                    trainHomeworkProblem.setHomeworkId(homeworkId);
                    trainHomeworkProblem.setProblemId(question.getProblemId());
                    trainHomeworkProblem.setScore(question.getScore());
                    trainHomeworkProblems.add(trainHomeworkProblem);
                });
                trainHomeworkProblemService.saveBatch(trainHomeworkProblems);
            }
        }

        return new ResponseDto().buildSucceed();
    }


    /**
     * 分配作业给某一个班级
     * @param trainClassId 班级id
     * @param homeworkId 作业id
     * @return
     */
    @RequestMapping("/assign-homework")
    @ResponseBody
    public ResponseDto assignHomework(Long trainClassId, Long homeworkId) {
        UserCache userInfo = UserInfoShareHolder.getUserInfo();
        TrainHomework homework = trainHomeworkService.getById(homeworkId);
        TrainClass trainClass = trainClassService.getById(trainClassId);
        if (homework == null || trainClass == null){
            return new ResponseDto().buildFail("参数校验错误");
        }
        if ( !(userInfo.getCompanyId().equals(homework.getCompanyId())
                && userInfo.getCompanyId().equals(trainClass.getCompanyId()) ) ){
            return new ResponseDto().buildFail("无权限操作");
        }

        TrainClassHomework trainClassHomework = trainClassHomeworkService.selectByHwIdAndClassId(homeworkId, trainClassId);
        if (trainClassHomework != null) {
            return new ResponseDto().buildFail("作业已经布置");
        }
        TrainClassHomework trainClassHomework1 = new TrainClassHomework();
        trainClassHomework1.setClassId(trainClassId);
        trainClassHomework1.setHomeworkId(homeworkId);
        trainClassHomeworkService.save(trainClassHomework1);
        log.info("【布置作业】用户：{}，为班级:{}-{},布置作业:{}-{},", userInfo.getUser().getId(),
                trainClass.getId(), trainClass.getName(), homework.getId(), homework.getTitle());
        return new ResponseDto().buildSucceed();
    }





    /**
     * 某一个班级移除某作业
     * @param trainClassId 班级id
     * @param homeworkId 作业id
     * @return
     */
    @RequestMapping("/remove-homework")
    @ResponseBody
    public ResponseDto removeHomework(Long trainClassId, Long homeworkId){
        UserCache userInfo = UserInfoShareHolder.getUserInfo();
        TrainHomework homework = trainHomeworkService.getById(homeworkId);
        TrainClass trainClass = trainClassService.getById(trainClassId);
        if (homework == null || trainClass == null){
            return new ResponseDto().buildFail("参数校验错误");
        }
        if (!(userInfo.getCompanyId().equals(homework.getCompanyId())
                && userInfo.getCompanyId().equals(trainClass.getCompanyId()) ) ){
            return new ResponseDto().buildFail("无权限操作");
        }
        TrainClassHomework trainClassHomework = trainClassHomeworkService.selectByHwIdAndClassId(homeworkId, trainClassId);
        if (trainClassHomework == null) {
            return new ResponseDto().buildFail("该作业未布置给该班级");
        }
        //校验是否有学生提交
        List<TrainHomeworkProblem> trainHomeworkProblems = trainHomeworkProblemService.queryByHwId(homeworkId);
        if (CollectionUtils.isEmpty(trainHomeworkProblems)){
            return new ResponseDto().buildFail("该作业无题目");
        }
        TrainHomeworkProblem trainHomeworkProblem = trainHomeworkProblems.get(0);
        List<TrainCommitRecord> trainCommitRecords = trainCommitRecordService.queryByHwIdAndPIdAndClassId(homeworkId, trainHomeworkProblem.getProblemId(), trainClassId);
        List<TrainCommitRecord> collect = trainCommitRecords.stream().filter(trainCommitRecord -> CommonUtil.isNotNullId(trainCommitRecord.getSubmitId())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(collect)){
            return new ResponseDto().buildFail("已有学生提交作业，不允许删除");
        }

        trainClassHomeworkService.deleteByHwIdAndClassId(homeworkId, trainClassId);
        log.info("【删除作业】用户：{}，为班级:{}-{},删除作业:{}-{},", userInfo.getUser().getId(),
                trainClass.getId(), trainClass.getName(), homework.getId(), homework.getTitle());
        return new ResponseDto().buildSucceed();
    }



    /**
     * 查询作业对应的所有题目id，查询到所有的id后，请从题库接口查询题目的具体信息，联系@huanghaoyu
     * @param homeworkId 作业id
     * @return
     */
    @RequestMapping("/homework-problems")
    @ResponseBody
    public ResponseDto<List<Long>> getHomeworkProblems(Long homeworkId){
        TrainHomework homework = trainHomeworkService.getById(homeworkId);
        if (homework == null){
            return new ResponseDto().buildFail("参数校验错误");
        }
        List<TrainHomeworkProblem> trainHomeworkProblems = trainHomeworkProblemService.queryByHwId(homeworkId);
        if (CollectionUtils.isEmpty(trainHomeworkProblems)){
            return new ResponseDto().buildSucceed();
        }
        List<Long> collect = trainHomeworkProblems.stream().map(TrainHomeworkProblem::getProblemId).collect(Collectors.toList());
        return new ResponseDto().buildSucceedHasData(collect);
    }


    /**
     * 根据homeworkId查询作业信息
     * @param homeworkId 作业id
     * @return
     */
    @RequestMapping("/homework-detail")
    @ResponseBody
    public ResponseDto<TrainHomework> getHomeworkDetail(Long homeworkId){
        TrainHomework homework = trainHomeworkService.getById(homeworkId);
        if (homework == null){
            return new ResponseDto().buildFail("参数校验错误");
        }
        return new ResponseDto().buildSucceedHasData(homework);
    }






    /**
     * 查询某个班级已经布置的作业
     * @param param 只需要传id和页数信息即可
     * @return
     */
    @RequestMapping("/train-class/all-homework")
    @ResponseBody
    public ResponseDto<Page<TrainHomework>> getTrainClassHomework(TrainClassUserParam param){
        UserCache userInfo = UserInfoShareHolder.getUserInfo();
        if (userInfo == null || param.getTrainClassId() == null) {
            return new ResponseDto().buildFail("未登录或参数校验错误");
        }
        TrainClass trainClass = trainClassService.getById(param.getTrainClassId());
        if (trainClass == null || !userInfo.getCompanyId().equals(trainClass.getCompanyId())) {
            return new ResponseDto().buildFail("无权限操作");
        }
        Page<TrainHomework> assignedHomeWorkForClass = trainHomeworkService.getAssignedHomeWorkForClass(param);
        return new ResponseDto().buildSucceedHasData(assignedHomeWorkForClass);
    }



    /**
     * 查询某个班级已经布置的作业-无分页
     * @classId
     * @return
     */
    @RequestMapping("/train-class/all-homework-no-page")
    @ResponseBody
    public ResponseDto<List<TrainHomework>> getAllTrainClassHomework(Long classId){
        UserCache userInfo = UserInfoShareHolder.getUserInfo();
        if (userInfo == null || CommonUtil.isNullId(classId)) {
            return new ResponseDto().buildFail("未登录或参数校验错误");
        }
        TrainClass trainClass = trainClassService.getById(classId);
        if (trainClass == null || !userInfo.getCompanyId().equals(trainClass.getCompanyId())) {
            return new ResponseDto().buildFail("无权限操作");
        }
        List<TrainHomework> allAssignedHomeWorkForClass = trainHomeworkService.getAllAssignedHomeWorkForClass(classId);
        return new ResponseDto().buildSucceedHasData(allAssignedHomeWorkForClass);
    }



    /**
     * 班级作业学生提交情况
     * @param param
     * @return
     */
    @RequestMapping("/class-homework/submit-detail")
    @ResponseBody
    public ResponseDto<Page<ClassUserSubmitInfoVo>> classHomeWorkSubmit(TrainClassUserParam param){
        /*UserCache userInfo = UserInfoShareHolder.getUserInfo();
        if (userInfo == null){
            return new ResponseDto<>().buildFail("未登录");
        }*/
        TrainClass trainClass = trainClassService.getById(param.getTrainClassId());
        if (trainClass == null){
            return new ResponseDto<>().buildFail("班级不存在");
        }
        //根据班级id查询学生
        Page<TrainClassUser> page = trainClassUserService.queryByParam(param);
        if (page.getTotal() == 0){
            return new ResponseDto().buildSucceed();
        }
        List<TrainClassUser> userInfos = page.getRecords();
        //目前是一个作业一题，交互就没啥问题
        Page<ClassUserSubmitInfoVo> result = new Page<>();
        result.setCurrent(page.getCurrent());
        result.setSize(page.getSize());
        result.setTotal(page.getTotal());
        List<TrainHomeworkProblem> trainHomeworkProblems = trainHomeworkProblemService.queryByHwId(param.getHomeworkId());
        if (CollectionUtils.isEmpty(trainHomeworkProblems)){
            return new ResponseDto().buildSucceed();
        }
        //表设计遗留问题 ------ 简单写
        TrainHomeworkProblem trainHomeworkProblem1 = trainHomeworkProblems.get(0);
        List<ClassUserSubmitInfoVo> recordVos = new ArrayList<>();
        result.setRecords(recordVos);
        for (TrainClassUser info : userInfos) {
            List<TrainCommitRecord> trainCommitRecords = trainCommitRecordService.queryByHwIdAndPIdAndClassIdAndUser(param.getHomeworkId(), trainHomeworkProblem1.getProblemId(), param.getTrainClassId(), info.getUserId());
            ClassUserSubmitInfoVo vo = new ClassUserSubmitInfoVo();
            vo.setProblemId(trainHomeworkProblem1.getProblemId());
            vo.setHomeworkId(param.getHomeworkId());
            vo.setTrainClassId(param.getTrainClassId());
            vo.setUserId(info.getUserId());
            vo.setRealName(info.getRealName());
            vo.setSubmitTime(new Date());
            if (CollectionUtils.isEmpty(trainCommitRecords)){
                vo.setSubmitTimes(0);
                vo.setSubmitStatus(0);
                vo.setSubmitStatus(TrainSubmitStatus.NOT_SUBMIT.getKey());
                recordVos.add(vo);
                continue;
            }
            trainCommitRecords.sort(Comparator.comparing(TrainCommitRecord::getSubmitTime, Comparator.reverseOrder()));
            int size = trainCommitRecords.stream().filter(trainCommitRecord -> CommonUtil.isNotNullId(trainCommitRecord.getSubmitId())).collect(Collectors.toList()).size();
            TrainCommitRecord record = trainCommitRecords.get(0);
            vo.setLastSubmitId(record.getSubmitId());
            vo.setSubmitStatus(record.getSubmitTime() == null ? TrainSubmitStatus.NOT_SUBMIT.getKey() : TrainSubmitStatus.SUBMIT.getKey());
            vo.setScore(record.getScore());
            vo.setSubmitTimes(size);
            recordVos.add(vo);
        }
        return new ResponseDto().buildSucceedHasData(result);
    }


    /**
     * 手动评分
     */
    @RequestMapping("/class-homework/chang-score")
    @ResponseBody
    public ResponseDto changScore(Long userId, Long submitId, Integer score){
        UserCache userInfo = UserInfoShareHolder.getUserInfo();

        trainCommitRecordService.changeScore(userId, submitId, score);
        return new ResponseDto().buildSucceed();
    }









}
